#coding=utf-8
from xml.dom.minidom import Document
import xml.dom.minidom
import os
from universal.root_path import dir_root

class SaveProjectToXml:
    def __init__(self,cfg,isProjectAddtoRecent):

        self.projectPath = cfg["projectPath"]
        self.task = cfg["projectTask"]

        self.labelImagsPath = self.getValue(cfg["labelImagesPath"])
        self.labelClasses = ','.join(cfg["labelClasses"]) #将列表转为字符串

        self.trainModel = self.getValue(cfg["trainModel"])
        self.trainPreWeightpath = self.getValue(cfg["trainPreWeightpath"])
        self.trainSaveWeigth = self.getValue(cfg["trainSaveWeigth"])
        self.trainInputImageSize = self.getValue(cfg["trainInputImageSize"])
        self.trainEpochs = self.getValue(cfg["epochs"])
        self.trainbatchSize = self.getValue(cfg["batchSize"])

        self.traintime = self.getValue(cfg["traintime"])
        self.trainValloss = self.getValue(cfg["trainValloss"])
        self.trainendEpochs = self.getValue(cfg["trainendEpochs"])
        self.trainDate = self.getValue(cfg["trainDate"])
        self.Precision = self.getValue(cfg["precision"])
        self.Recall = self.getValue(cfg["recall"])
        self.mAP = self.getValue(cfg["mAP"])

        self.testImgsPath = self.getValue(cfg["testImgsPath"])
        self.testModelPath = self.getValue(cfg["testModelPath"])
        self.testSaveOKimgsPath = self.getValue(cfg["SaveOKimgsPath"])
        self.testSaveNGimgsPath = self.getValue(cfg["SaveNGimgsPath"])
        self.testScore = self.getValue(cfg["testScore"])
        self.testIOU = self.getValue(cfg["testIOU"])

        self.totaltestimgs = self.getValue(cfg["totaltestimgs"])
        self.ngImgsNum = self.getValue(cfg["ngImgsNum"])
        self.ngImgsRate = self.getValue(cfg["ngImgsRate"])
        self.totaltesttime = self.getValue(cfg["totaltesttime"])
        self.testDate = self.getValue(cfg["testDate"])

        doc = Document()
        project = doc.createElement('ODVisionProject')
        doc.appendChild(project)

        #工程名称
        projectMessages = doc.createElement('ProjectMessages')
        project.appendChild(projectMessages)
        self.insertElementOrder(doc,projectMessages,'projectPath',self.projectPath)
        self.insertElementOrder(doc,projectMessages,'projectTask',self.task)

        #标注
        label = doc.createElement('Label')
        project.appendChild(label)
        self.insertElementOrder(doc,label,'LabelImagesPath',self.labelImagsPath)
        self.insertElementOrder(doc,label,'LabelClasses',self.labelClasses)

        #训练
        train = doc.createElement('Train')
        project.appendChild(train)
        trainSettings = doc.createElement('TrainingSettings')
        train.appendChild(trainSettings)
        self.insertElementOrder(doc,trainSettings,'TrainModel',self.trainModel)
        self.insertElementOrder(doc,trainSettings,'LoadPreTrainingWeight',self.trainPreWeightpath)
        self.insertElementOrder(doc,trainSettings,'SaveWeightPath',self.trainSaveWeigth)
        self.insertElementOrder(doc,trainSettings,'InputImagesSize',self.trainInputImageSize)
        self.insertElementOrder(doc,trainSettings, 'Epochs', self.trainEpochs)
        self.insertElementOrder(doc,trainSettings, 'BatchSize', self.trainbatchSize)

        #训练结果
        trainResults = doc.createElement('TrainingResults')
        train.appendChild(trainResults)
        self.insertElementOrder(doc,trainResults,'TrainTime',self.traintime)
        self.insertElementOrder(doc,trainResults,'TrainValLoss',self.trainValloss)
        self.insertElementOrder(doc,trainResults,'TrainEndEpochs',self.trainendEpochs)
        self.insertElementOrder(doc,trainResults,'TrainDate',self.trainDate)
        self.insertElementOrder(doc,trainResults,'Precision',self.Precision)
        self.insertElementOrder(doc,trainResults,'Recall',self.Recall)
        self.insertElementOrder(doc,trainResults,'mAP',self.mAP)

        #测试
        test = doc.createElement('Test')
        project.appendChild(test)
        testSettings = doc.createElement('TestSettings')
        test.appendChild(testSettings)
        self.insertElementOrder(doc,testSettings,'TestImagesPath',self.testImgsPath)
        self.insertElementOrder(doc,testSettings,'TestModelPath',self.testModelPath)
        self.insertElementOrder(doc,testSettings,'SaveOKImages',self.testSaveOKimgsPath)
        self.insertElementOrder(doc,testSettings,'SaveNGImages',self.testSaveNGimgsPath)
        self.insertElementOrder(doc,testSettings, 'Score', self.testScore)
        self.insertElementOrder(doc,testSettings, 'IOU', self.testIOU)

        #测试结果
        testResults = doc.createElement('TestResults')
        test.appendChild(testResults)
        self.insertElementOrder(doc,testResults,'TotalTestImages',self.totaltestimgs)
        self.insertElementOrder(doc,testResults,'NGImagesNum', self.ngImgsNum)
        self.insertElementOrder(doc,testResults,'NGImagesRate', self.ngImgsRate)
        self.insertElementOrder(doc,testResults,'TotalTestTime', self.totaltesttime)
        self.insertElementOrder(doc,testResults,'TestDate', self.testDate)

        with open(cfg["projectPath"],'wb') as f:
            f.write(doc.toprettyxml(indent='\t', encoding='utf-8'))

        #将project文件添加至最近文档列表
        # recentProjectList = []
        # if isProjectAddtoRecent:
        #     with open('recentProject.txt','r') as f:
        #         recentProjectList = f.readlines()

        if isProjectAddtoRecent:
            recentpro = dir_root() + os.sep + 'Config/recentProject.txt'
            if os.path.exists(recentpro) is False:
                open(recentpro, 'w+')   #判断这个文件是否存在
            with open(recentpro, 'r') as f:     #打开文件，读一下工程路径
                recentProjectList = f.readlines()
            recentProjectList = [x.split('\n')[0] for x in recentProjectList]
            if cfg["projectPath"] not in recentProjectList:
                recentProjectList.append(cfg["projectPath"])
            os.remove(recentpro)
            with open(recentpro,'a+') as f:
                for x in recentProjectList:
                    f.write(x+'\n')

    def getValue(self,value):
        if value ==''or value==None:
            value = ''
        return str(value)

    def insertElementOrder(self,doc,upperOrder,orderName,orderText):
        order = doc.createElement(orderName)
        order_Text = doc.createTextNode(orderText)
        order.appendChild(order_Text)
        upperOrder.appendChild(order)

class ParseXml:
    def __init__(self,projectFilePath):
        self.projectFilePath = projectFilePath

        # 使用minidom解析器打开 XML 文档
    def parseXml(self):
        DOMTree = xml.dom.minidom.parse(self.projectFilePath)
        ODVisionProject = DOMTree.documentElement
        #---------获取ODVisionProject下的一级目录----------
        messages = ODVisionProject.getElementsByTagName('ProjectMessages')
        label = ODVisionProject.getElementsByTagName('Label')
        train = ODVisionProject.getElementsByTagName("Train")
        test = ODVisionProject.getElementsByTagName("Test")

        #---------<ProjectMessages>↓↓↓↓↓↓↓↓↓↓----------
        projectPath = messages[0].getElementsByTagName('projectPath')[0].childNodes[0].data
        projectTask = messages[0].getElementsByTagName('projectTask')[0].childNodes[0].data

        #---------<Label>↓↓↓↓↓↓↓↓↓↓---------
        labelImgsPath = self.getValue_kong(label[0].getElementsByTagName('LabelImagesPath')[0].childNodes)
        labelClasses = self.getValue_kong(label[0].getElementsByTagName("LabelClasses")[0].childNodes)
        if labelClasses != '':
            labelClasses = labelClasses.split(',')


        #---------<Train>-><Trainsettings>↓↓↓↓↓↓↓↓↓↓---------
        TrainingSettings = train[0].getElementsByTagName("TrainingSettings")
        TrainModel = self.getValue_kong(TrainingSettings[0].getElementsByTagName("TrainModel")[0].childNodes)
        PreTrainingWeight = self.getValue_kong(TrainingSettings[0].getElementsByTagName("LoadPreTrainingWeight")[0].childNodes)
        SaveWeightPath = self.getValue_kong(TrainingSettings[0].getElementsByTagName("SaveWeightPath")[0].childNodes)
        InputImagesSize = self.getValue_kong(TrainingSettings[0].getElementsByTagName("InputImagesSize")[0].childNodes)
        Epochs = self.getValue_kong(TrainingSettings[0].getElementsByTagName("Epochs")[0].childNodes)
        BatchSize = self.getValue_kong(TrainingSettings[0].getElementsByTagName("BatchSize")[0].childNodes)


        #---------<Train>-><TrianResult>↓↓↓↓↓↓↓↓↓↓---------
        TrainingResults = train[0].getElementsByTagName("TrainingResults")
        TrainTime = self.getValue_kong(TrainingResults[0].getElementsByTagName("TrainTime")[0].childNodes)
        TrainValLoss = self.getValue_kong(TrainingResults[0].getElementsByTagName("TrainValLoss")[0].childNodes)
        TrainEndEpochs = self.getValue_kong(TrainingResults[0].getElementsByTagName("TrainEndEpochs")[0].childNodes)
        TrainDate = self.getValue_kong(TrainingResults[0].getElementsByTagName("TrainDate")[0].childNodes)
        Precision = self.getValue_kong(TrainingResults[0].getElementsByTagName("Precision")[0].childNodes)
        Recall = self.getValue_kong(TrainingResults[0].getElementsByTagName("Recall")[0].childNodes)
        mAP = self.getValue_kong(TrainingResults[0].getElementsByTagName("mAP")[0].childNodes)


        #---------<Test>-><TestSettings>↓↓↓↓↓↓↓↓↓↓---------
        TestSettings = test[0].getElementsByTagName("TestSettings")
        TestImagesPath = self.getValue_kong(TestSettings[0].getElementsByTagName("TestImagesPath")[0].childNodes)
        TestModelPath = self.getValue_kong(TestSettings[0].getElementsByTagName("TestModelPath")[0].childNodes)
        SaveOKImages = self.getValue_kong(TestSettings[0].getElementsByTagName("SaveOKImages")[0].childNodes)
        SaveNGImages = self.getValue_kong(TestSettings[0].getElementsByTagName("SaveNGImages")[0].childNodes)
        Score = self.getValue_kong(TestSettings[0].getElementsByTagName("Score")[0].childNodes)
        IOU = self.getValue_kong(TestSettings[0].getElementsByTagName("IOU")[0].childNodes)


        #---------<Test>-><TestResults>↓↓↓↓↓↓↓↓↓↓---------
        TestResults = test[0].getElementsByTagName("TestResults")
        TotalTestImages = self.getValue_kong(TestResults[0].getElementsByTagName("TotalTestImages")[0].childNodes)
        NGImagesNum = self.getValue_kong(TestResults[0].getElementsByTagName("NGImagesNum")[0].childNodes)
        NGImagesRate = self.getValue_kong(TestResults[0].getElementsByTagName("NGImagesRate")[0].childNodes)
        TotalTestTime = self.getValue_kong(TestResults[0].getElementsByTagName("TotalTestTime")[0].childNodes)
        TestDate = self.getValue_kong(TestResults[0].getElementsByTagName("TestDate")[0].childNodes)


        self.para_Cfg = {"projectPath": projectPath,
                  "projectTask": projectTask,

                  "labelImagesPath": labelImgsPath,
                  "labelClasses": labelClasses,

                  "trainModel": TrainModel,
                  "trainPreWeightpath": PreTrainingWeight,
                  "trainSaveWeigth": SaveWeightPath,
                  "trainInputImageSize": InputImagesSize,
                  "epochs": Epochs,
                  "batchSize": BatchSize,

                  "traintime": TrainTime,
                  "trainValloss": TrainValLoss,
                  "trainendEpochs": TrainEndEpochs,
                  "trainDate": TrainDate,
                  "precision": Precision,
                  "recall": Recall,
                  "mAP": mAP,

                  "testImgsPath": TestImagesPath,
                  "testModelPath": TestModelPath,
                  "SaveOKimgsPath": SaveOKImages,
                  "SaveNGimgsPath": SaveNGImages,
                  "testScore": Score,
                  "testIOU": IOU,

                  "totaltestimgs": TotalTestImages,
                  "ngImgsNum": NGImagesNum,
                  "ngImgsRate": NGImagesRate,
                  "totaltesttime": TotalTestTime,
                  "testDate": TestDate,

        }

        return self.para_Cfg

    def getValue_kong(self,value):
        if value == []:
            value = ''
        else:
            value = value[0].data
        return value

class GetTrainAndTest_value:
    def __init__(self,train,test):
        self.trainWidget = train
        self.testWidget = test

    def GetValue(self):
        trainModel = self.trainWidget.modelComBox.currentText().strip()
        trainPreWeightpath = self.trainWidget.weightpathLineEdit.text().strip()
        trainInputImageSize = self.trainWidget.imgSizeComBox.currentText().strip()
        trainEpochs = self.trainWidget.epochsLineEdit.text()
        trainbatchSize = self.trainWidget.batchsizeLineEdit.text()

        traintime = self.trainWidget.AlreadyTime_txt
        trainValloss = self.trainWidget.loss
        trainendEpochs = self.trainWidget.epochEnd
        trainDate = self.trainWidget.TrainDate
        Precision = self.trainWidget.Precision
        Recall = self.trainWidget.Recall
        mAP = self.trainWidget.mAP50
        testImgsPath = self.testWidget.testimgspathLineEdit.text().strip()
        testModelPath = self.testWidget.weightpathLineEdit.text().strip()
        testScore = self.testWidget.scoreLineEdit.text().strip()

        totaltestimgs = self.testWidget.TotalTestImages
        ngImgsNum = self.testWidget.NGImagesNum
        ngImgsRate = self.testWidget.NGImagesRate
        totaltesttime = self.testWidget.TestTime
        testDate = self.testWidget.TestDate

        OKImage_path = self.testWidget.SaveOKImages
        NGImage_path = self.testWidget.SaveNGImages

        od_cfg = {"projectPath": '',
                  "projectTask": '',

                  "labelImagesPath": '',
                  "labelClasses": '',

                  "trainModel": trainModel,
                  "trainPreWeightpath": trainPreWeightpath,
                  "trainSaveWeigth": '',
                  "trainInputImageSize": trainInputImageSize,
                  "epochs": trainEpochs,
                  "batchSize": trainbatchSize,

                  "traintime": traintime,
                  "trainValloss": trainValloss,
                  "trainendEpochs": trainendEpochs,
                  "trainDate": trainDate,
                  "precision": Precision,
                  "recall": Recall,
                  "mAP": mAP,

                  "testImgsPath": testImgsPath,
                  "testModelPath": testModelPath,
                  "SaveOKimgsPath": OKImage_path,
                  "SaveNGimgsPath": NGImage_path,
                  "testScore": testScore,
                  "testIOU": '',

                  "totaltestimgs": totaltestimgs,
                  "ngImgsNum": ngImgsNum,
                  "ngImgsRate": ngImgsRate,
                  "totaltesttime": totaltesttime,
                  "testDate": testDate,
                  }
        return od_cfg

def GetValue_None():
    od_cfg = {"projectPath": '',
           "projectTask": '',

           "labelImagesPath": '',
           "labelClasses":'',
           "trainModel": '/',
           "trainPreWeightpath": '/',
           "trainSaveWeigth": '',
           "trainInputImageSize": '/',
           "epochs": '/',
           "batchSize": '/',

           "traintime": '/',
           "trainValloss": '/',
           "trainendEpochs":'/',
           "trainDate": '/',
           "precision": '/',
           "recall": '/',
           "mAP": '/',

           "testImgsPath": '/',
           "testModelPath": '/',
           "SaveOKimgsPath": '/',
           "SaveNGimgsPath":'/',
           "testScore":'/',
           "testIOU": '',

           "totaltestimgs": '/',
           "ngImgsNum": '/',
           "ngImgsRate": '/',
           "totaltesttime":'/',
           "testDate": '/',
              }
    return od_cfg

